package com.liang.exam.utils;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Component
public class TokenValidator {

    private Cache<String, String> localCache = Caffeine.newBuilder()
            .expireAfterWrite(10, TimeUnit.MINUTES) // 本地缓存10分钟
            .maximumSize(1000) // 最大缓存1000条
            .build();

    private StringRedisTemplate stringRedisTemplate;

    // 构造方法注入 RedisTemplate
    @Autowired
    public TokenValidator(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    // 校验Token是否有效
    public void validateToken(String token) {
        // 从本地缓存获取Token
        String redisToken = localCache.getIfPresent(token);
        if (redisToken == null) {
            // 本地缓存未命中，从Redis获取
            redisToken = stringRedisTemplate.opsForValue().get(token);
            if (redisToken == null) {
                // Redis中也不存在，Token失效
                throw new RuntimeException("Token已失效");
            }
            // 将Token存入本地缓存
            localCache.put(token, redisToken);
        }
    }

    public void storeToken(String token) {
        // 存储到 Redis
        ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
        operations.set(token, token, 1, TimeUnit.HOURS);
        // 存储到本地缓存
        localCache.put(token, token);
    }

    public void invalidateToken(String token) {
        // 从 Redis 中删除
        stringRedisTemplate.delete(token);
        // 从本地缓存中删除
        localCache.invalidate(token);
    }

}
